home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / std / c++ / 694 < prev    next >
Encoding:
Text File  |  1996-08-06  |  8.1 KB  |  225 lines

  1. Path: chronicle.mti.sgi.com!austern
  2. From: bonnardv@pratique.fr (Valentin Bonnard)
  3. Newsgroups: comp.std.c++
  4. Subject: Re: Some ideas about C++ and a question
  5. Date: 12 Mar 1996 20:23:00 PST
  6. Organization: -
  7. Approved: austern@isolde.mti.sgi.com
  8. Message-ID: <v01530500ad6a43009478@[194.98.4.120]>
  9. NNTP-Posting-Host: isolde.mti.sgi.com
  10. Content-Type: text/plain; charset="us-ascii"
  11. X-Original-Date: Mon, 11 Mar 1996 19:52:52 -0100
  12. X-Sender: bonnardv@mail.pratique.fr
  13. X-Mailer: Eudora F1.5.3
  14. X-Auth: PGPMoose V1.1 PGP comp.std.c++
  15.     iQBVAwUBMUZNtky4NqrwXLNJAQG6TAH/RjYMh3w/+/89KJPFM79UQvEPc29OkYme
  16.     bnDqlyI84/gJ8PYLxpPCyReWaAlMelMMGknLLRKFrU61tI52BNq4+Q==
  17.     =4ZkX
  18. Originator: austern@isolde.mti.sgi.com
  19.  
  20. [Note: I have tried to post normally this followup, but it seam it 
  21. didn't work; this follows news:4hdctd$r1p@engnews1.Eng.Sun.COM (Steve 
  22. Clamage's article) Please remove this note before posting. ]
  23.  
  24. clamage@Eng.Sun.COM (Steve Clamage) wrote:
  25. >Valentin Bonnard <bonnardv@pratique.fr> writes:
  26. >
  27. >>I have 4 ideas about C++ and a question.
  28. >
  29. >>1) String literals
  30. >>~~~~~~~~~~~~~~~~~~
  31. >>String literals should be const char* instead of char* (if it is not
  32. >>already the case).
  33. >
  34. >Yes, it is clearly the "right" thing to do, but it is not the case
  35. >for the same reason it is not the case in Standard C: it would break
  36. >too much existing code to make the change.
  37.  
  38. Perhaps, but in C void* converted to anything* and it's not the case in C++: this broke more C code (I think, or a least more of my old C code) then what I propose.
  39.  
  40. Or could it be a compiler option (that all compilers should have) to make string literals char* ?
  41.  
  42.  
  43. >>2) Placement operators
  44. >>~~~~~~~~~~~~~~~~~~~~~~
  45. >>class Object {
  46. >>        void    operator+ // or / or whatever
  47. >>                         (Object& result, const Object& b) const;
  48. binary (compute *this + b, put the result in 'result')
  49. >>        void    operator* (Object& result) const;     #2
  50. unary (compute *(*this), put the result in 'result')
  51. >>        Object  operator* (const Object& result) const; // old one
  52.                                            ^^^^^^ ops! should be named b
  53. binary (compute *this + b, return the result)
  54. >>}
  55. >
  56. >>should be called respectively by:
  57. >>a = b + c;
  58. >
  59. >>and a = *b;
  60. >
  61. >>and (old one) a*b;
  62. >
  63. >>This will solve the [well-known] problem of copying the result into a temporary.
  64. >>The compatibility will be preserved since old syntax will be allowed to.
  65. >
  66. >You will have to present this idea in more detail. I can't figure out
  67. >what you are proposing. It looks like you want the function marked #2
  68. >to be some form of unary dereferencing operator, but that would change
  69. >its existing meaning of a member binary (multiplication) operator.
  70.  
  71. The story begin with a class Object for the construction and destruction is not trivial (and take some time):
  72.  
  73. Object  a, b, c;
  74. a = b @ c;
  75.  
  76. where @ is one of: + - * / % & | ^ && || etc... (but not one of: += -= *= /= %= &= |= ^=)
  77.  
  78. I want to be able to write (using the friend notation to make it a little more clear):
  79. void    operator @ (Object& result, const Object& a, const Object& b);
  80.  
  81. instead of 
  82. Object    operator @ (const Object& a, const Object& b);
  83.  
  84. The definition would become (for example):
  85.  
  86. void    operator @ (Object& result, const Object& a, const Object& b)
  87. {
  88.     result = a;
  89.     result @= b; // direct operation
  90. }
  91.  
  92. rather than
  93. Object    operator @ (const Object& a, const Object& b)
  94. {
  95.     Object result = a;
  96.     result @= b;
  97.  
  98.     return Object;      // temporary created with copy constructor, Object deleted,
  99. }                       // then temporary copied into a, and temporary deleted
  100.  
  101. The old style should still be allowed, and the operator signature is clearly distinct from the one I propose.
  102.  
  103. For unary operators, the idea is exactly the same, but it's a bit more difficult to see if it's a binary operator or a unary operator because my syntax and an argument:
  104. (where @ is one of ! ~ unary * etc...)
  105.  
  106. Object  operator @ (const Object&); // again friend version instead of member version
  107. become
  108. void    operator @ (Object&, const Object&); // unary [2]
  109.  
  110. The problem with * is that the [2] is difficult to distinguish from
  111. Object  operator * (const Object&, const Object&); // binary *, return the result
  112.  
  113. But my operator return void, so it could be used as an indication: I don't think many people currently have code with
  114. void operator * (Object&, const Object&); // I think this is currently legal
  115. and who write a * b; where a will be modified !
  116.  
  117. This king of strange code would break if my proposal was accepted for unary operators, but I really don't think it is very serious.
  118.  
  119. >>3) Use of explicit keyword
  120. >>~~~~~~~~~~~~~~~~~~~~~~~~~~
  121. >
  122. >>void    foo (explicit Derived* object) ...
  123. >
  124. >Evidently you want this to mean that "*object" is of type "Derived"
  125. >and not of any type derived from "Derived". I guess I don't see
  126. >the utility of the declaration. You can create a type which cannot be
  127. >derived from, if that is what you want. If you don't want that, I
  128. >don't see why the author of "foo" wants to be sure no derived type
  129. >is ever passed to it. What programming problem is being solved here?
  130. >
  131. >The whole idea of public derivation is that a derived type can be
  132. >used where ever a base type is expected. Why does the author of foo
  133. >want to ensure that the actual object has, for example, no additional
  134. >data, functionality, or instrumentation, when the author of Derived
  135. >has no objections to the possibility?
  136. >
  137. >If for some reason you do care about the actual type of *object,
  138. >wouldn't it be enough to use an RTTI expression in the function?
  139.  
  140. This could help for functions that take a Base[]:
  141.  
  142. class Base {
  143.     public:
  144.         void    (*func) ();
  145. };
  146.  
  147. class Derived {
  148.     public:
  149.         long    dummy;
  150. };
  151.  
  152. void    foo_safe (explicit Base[]);
  153. void    foo_bad (Base[]);
  154.  
  155. void    test ()
  156. {
  157.     Base*     der = new Derived[10];
  158.  
  159.     foo_bad (der); // pass at compile time, then crash
  160.     foo_safe (der);
  161. // the compiler will tell you 'cannot convert from Base* to explicit Base*'
  162. }
  163.  
  164. void    foo_bad (Base[] b)
  165. {
  166.     for (int i=0; i<10; i++)
  167.         (b[i].func) (); // function call here to be sure that it crash ;->
  168. }
  169.  
  170. void    foo_safe (explicit Base[] b) // do the same thing
  171. {
  172.     for (int i=0; i<10; i++)
  173.         (b[i].func) ();
  174. }
  175.  
  176. I know a could use a container, but the notion of array use sometimes useful for class too.
  177.  
  178. Well, this was not the point of my idea: I wanted to the compiler to know at compile time the 'real' type of the object, not:
  179. - use RTTI (contrary of compile time !)
  180. - not just to protect from error (see example above)
  181. - 'create a type which cannot be derived from', as Steve Clamage say.
  182.   (The class Derived can be derived from, since, it has a normal declaration.)
  183.  
  184. I wrote:
  185. > object.VirtualFunc (); // nop (compiler does not generate code for this)
  186.  
  187. Since VirtualFunc is virtual, the compiler must generate code for it, even when object is a Base& and Base::VirtualFunc is defined as { } *except* if:
  188. (a) the variable is passed by value
  189. (b) you use explicit
  190.  
  191. (a) as obvious disadvantages in terms of speed for big classes, so the last solution is (b)...
  192.  
  193. Note: the rule for the qualifier are the *inverse* of the rules for cv (const/volatile):
  194. ~~~~~
  195. T* -> const T*          const T* !=> T*
  196. T* -> volatile T*       volatile T* !=> T*
  197. but
  198. explicit T* -> T*       T* !=> explicit T*
  199.  
  200. where -> means can be converted to and !=> means CAN'T be converted to.
  201.  
  202.  
  203. >>4) Conversion of Type** to const Type**
  204. >>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  205. >
  206. >>It's ok, this is an error; but why cannot Type** be converted to const Type* 
  207. >>const* ?
  208. >
  209. >For the same reason: it could cause a violation of constness without
  210. >a cast. The draft standard does allow Type** to be converted to
  211. >"Type*const*", since that cannot cause any such violation.
  212.  
  213. I don't see how you could violate constness _without_ the cast; if you know, please tell me.
  214.  
  215.  
  216. Valentin Bonnard
  217. bonnardv@pratique.fr
  218. ---
  219. [ comp.std.c++ is moderated.  To submit articles: Try just posting with your 
  220.                 newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  221.   comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  222.   Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  223.   Comments? mailto:std-c++-request@ncar.ucar.edu 
  224. ]
  225.